/**
 * Author shuqi
 * Rev
 * Date: 2020-01-01 12:34
 * <p>
 * Copyright (C) 2020 Seeyon, Inc. All rights reserved.
 * <p>
 * This software is the proprietary information of Seeyon, Inc.
 * Use is subject to license terms.
 *
 * @company seeyon.com
 * @author shuqi
 * @since V5 V8.0
 */
package com.shuqi.tools.utils;

import com.shuqi.tools.CMPHelper;
import com.shuqi.tools.dto.BuildConfig;
import com.shuqi.tools.dto.Manifest;
import com.shuqi.utils.JSONUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.FileWriterWithEncoding;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * <p>文件同步服务</p>
 * @date 2020-01-01 12:34
 * @since V5 V8.0
 * @author shuqi
 */
public class SyncUtils {
	/**
	 * 支持自动同步的文件后缀
	 */
	private static List<String> autoSyncExt =  Arrays.asList("js","css","json","svg","ttf","eot","woff","png","jpg","bmp","jpeg","properties");
	/**
	 * 目标文件目录
	 */
	private static final String syncTargetPath = "%s"  + File.separator + "m3"  + File.separator
			+ "apps"  + File.separator + "%s"  + File.separator + "%s%s";

	/**
	 * 判断目录是否为M3应用目录
	 * @param path
	 * @return
	 */
	public static boolean isAppPath(String path){
		String mateInfoPath  = String.format(Constants.manifestPath,path);
		if(new File(mateInfoPath).exists()){
			return true;
		}
		return false;
	}
	/**
	 * 判读path 是否为 rootPath的子目录
	 * @param path
	 * @param rootPath
	 * @return
	 */
	private static boolean isSubPath(String path,String rootPath){
		return path.replace('\\','/').startsWith(rootPath.replace('\\','/'));
	}

	private static File findRootPath(String path, String m3SourcePath,int depth) throws Exception {
		File root = new File(m3SourcePath);
		if(isAppPath(m3SourcePath)){
			return root;
		}
		if(depth > 2){
			return null;//
		}
		for (File file : root.listFiles()) {
			if(!file.isDirectory()){
				continue;
			}
			String fpath = file.getCanonicalPath();
			if(!isSubPath(path,file.getCanonicalPath())){
				continue;
			}
			if(isAppPath(m3SourcePath)){
				return file;
			}
			return findRootPath(path,fpath , depth + 1);
		}
		return null;
	}
	/**
	 * 同步文件
	 * @param path  文件目录
	 * @param cmpHelper 配置
	 */
	public static void syncFile(String path, CMPHelper cmpHelper) throws Exception {
		BuildConfig config = cmpHelper.getConfig();
		if(!config.isOK()){
			return;
		}
		if(!isSubPath(path,config.getM3SourcePath())){
			return;
		}
		boolean isAllow = false;
		for (String s : autoSyncExt) {
			if(path.endsWith(s)){
				isAllow = true;
				break;
			}
		}
		if(!isAllow){
			return;
		}
		File rootAppPath = findRootPath(path,config.getM3SourcePath(),0);
		if(rootAppPath == null){
			LoggerUtils.info(path + " : 无法确定app目录");
			return;
		}
		File srcFile = new File(path);


		// 读取manifest.json
		File mateInfoFile = new File(String.format(Constants.manifestPath,rootAppPath.getCanonicalPath()));
		String mateJson = FileUtils.readFileToString(mateInfoFile, "utf-8");
		Manifest mateMap = JSONUtils.parseJson(mateJson, Manifest.class);

		String relativePath = path.substring(rootAppPath.getCanonicalPath().length());
		// ${v5RuntimePath}/m3/apps/${manifestJson.team}/${manifestJson.bundleName}${relativePath}
		String targetFileName = String.format(syncTargetPath, config.getV5RuntimePath(), mateMap.getTeam(), mateMap.getBundleName(),relativePath);
		File targetFile = new File(targetFileName);
		if(path.endsWith("properties")){
			covertPropToJS(srcFile,new File(targetFile.getParent(),targetFile.getName().replaceAll("\\.properties", "\\.js")));
		}else{
			LoggerUtils.info(path + " ===> " + targetFileName);
			try {
				FileUtils.copyFile(srcFile, targetFile);
			} catch (IOException e) {
				LoggerUtils.error("", e);
			}
		}


	}

	/**
	 * 将properties 转换为 js 国际化文件
	 * @param srcFile
	 * @param targetFile
	 */
	public static void  covertPropToJS(File srcFile,File targetFile){
		FileWriterWithEncoding out = null;
		try {
			out = new FileWriterWithEncoding(targetFile, "utf-8");
			Properties pp = new Properties();
			pp.load(new FileInputStream(srcFile));
			out.write(String.format("/** auto create by cmpHelper at %s **/",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
			out.write("\r\n");
			out.write("if(typeof fI18nData == \"undefined\"){");
			out.write("\r\n");
			out.write("    fI18nData = {};");
			out.write("\r\n");
			out.write("}");
			out.write("\r\n");
			for (Map.Entry<Object, Object> entry : pp.entrySet()) {
				try {
					String val = entry.getValue().toString();
					out.write(String.format("fI18nData[\"%s\"]=\"", entry.getKey()));
					out.write(val.replace("\"", "\\\""));
					out.write("\";");
					out.write("\r\n");
				}catch (Exception e){
					LoggerUtils.error("", e);
				}
			}
		} catch (IOException e) {
			LoggerUtils.error("", e);
		}finally {
			IOUtils.closeQuietly(out);
		}
	}

}
